//package com.shoulder.authorizationserver.autoconfigure;
//
//import cn.hutool.core.collection.CollUtil;
//import cn.hutool.core.util.ArrayUtil;
//import com.shoulder.resourceserver.entrypoint.SecurityAuthenticationEntryPoint;
//import com.shoulder.resourceserver.handler.PasswordEncoderHandler;
//import com.shoulder.resourceserver.handler.SecurityAccessDeniedHandler;
//import com.shoulder.core.annotation.Anonymous;
//import com.shoulder.core.filter.LauncherXssFilter;
//import com.shoulder.core.properties.SecurityProperties;
//import com.shoulder.core.properties.XssProperties;
//import com.shoulder.core.util.FreeUtils;
//import com.shoulder.imports.Imports;
//import org.springframework.boot.autoconfigure.AutoConfiguration;
//import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
//import org.springframework.boot.context.properties.EnableConfigurationProperties;
//import org.springframework.context.ApplicationContext;
//import org.springframework.context.annotation.Bean;
//import org.springframework.core.annotation.Order;
//import org.springframework.security.config.Customizer;
//import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
//import org.springframework.security.config.annotation.web.builders.HttpSecurity;
//import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
//import org.springframework.security.core.userdetails.User;
//import org.springframework.security.core.userdetails.UserDetails;
//import org.springframework.security.core.userdetails.UserDetailsService;
//import org.springframework.security.crypto.password.PasswordEncoder;
//import org.springframework.security.oauth2.server.resource.web.BearerTokenResolver;
//import org.springframework.security.provisioning.InMemoryUserDetailsManager;
//import org.springframework.security.web.AuthenticationEntryPoint;
//import org.springframework.security.web.SecurityFilterChain;
//import org.springframework.security.web.access.AccessDeniedHandler;
//import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
//import org.springframework.web.method.HandlerMethod;
//import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
//import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
//
//import java.util.List;
//import java.util.Map;
//
//@Imports(value = AutoConfiguration.class)
//@AutoConfiguration
//@EnableWebSecurity
//@EnableConfigurationProperties({SecurityProperties.class, XssProperties.class})
//@EnableMethodSecurity
//public class DefaultSecurityAutoConfiguration {
//
//    /**
//     * 配置 spring security 相关的过滤器链
//     *
//     * @param http
//     * @return
//     * @throws Exception
//     */
//    @Bean
//    @Order(2)
//    public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http
//            , AccessDeniedHandler accessDeniedHandler
//            , AuthenticationEntryPoint authenticationEntryPoint
//            , SecurityProperties securityProperties
//            , XssProperties xssProperties
//            , ApplicationContext applicationContext
//            , BearerTokenResolver bearerTokenResolver)
//            throws Exception {
//
//        List<String> excludeUrls = securityProperties.getExcludeUrls();
//
//        // 20240202: 实际在使用过程中去Nacos或者其他配置文件进行 url 的配置觉得很麻烦,于是添加了 注解方式 支持
//        Map<RequestMappingInfo, HandlerMethod> methods = applicationContext.getBean(RequestMappingHandlerMapping.class).getHandlerMethods();
//
//        methods.forEach((info, method) -> {
//            Anonymous anonymous = method.getMethodAnnotation(Anonymous.class);
//            if (anonymous != null) {
//                excludeUrls.addAll(info.getPathPatternsCondition().getPatternValues());
//            }
//        });
//        String[] urls = CollUtil.isEmpty(excludeUrls) ? FreeUtils.build() : FreeUtils.build(ArrayUtil.toArray(excludeUrls, String.class));
//
//        http.authorizeHttpRequests((authorize) -> authorize
//                        .requestMatchers(urls).permitAll()
//                        .anyRequest().authenticated()
//                )
//                .csrf(csrfConfigurer -> csrfConfigurer.disable())
//                .cors(corsConfigurer -> corsConfigurer.disable())
//                // Form login handles the redirect to the login page from the
//                // authorization server filter chain
//                .formLogin(Customizer.withDefaults())
//                .addFilterBefore(new LauncherXssFilter(xssProperties), UsernamePasswordAuthenticationFilter.class)
//                //添加BearerTokenAuthenticationFilter，将认证服务当做一个资源服务，解析请求头中的token
//                .oauth2ResourceServer((resourceServer) -> resourceServer
//                        //自定义 Bearer Token 的请求头,区分系统的 Authorization 请求头
//                        .bearerTokenResolver(bearerTokenResolver)
//                        .accessDeniedHandler(accessDeniedHandler)
//                        .authenticationEntryPoint(authenticationEntryPoint)
//                        .jwt(Customizer.withDefaults()));
//        return http.build();
//    }
//
//    /**
//     * 配置PasswordEncoder
//     *
//     * @return
//     */
//
//    @Bean
//    public PasswordEncoder passwordEncoder() {
//        return PasswordEncoderHandler.createDelegatingPasswordEncoder();
//    }
//
//    /**
//     * 自定义权限异常
//     *
//     * @return
//     */
//    @Bean
//    public AccessDeniedHandler accessDeniedHandler() {
//        return new SecurityAccessDeniedHandler();
//    }
//
//    /**
//     * 自定义认证异常
//     *
//     * @return
//     */
//    @Bean
//    public AuthenticationEntryPoint authenticationEntryPoint() {
//        return new SecurityAuthenticationEntryPoint();
//    }
//
//
//    /**
//     * 配置基于内存的登录用户信息
//     * 实际项目中重新定义个 UserDetailsService 的 bean,这里做测试用
//     *
//     * @return
//     */
//    @Bean
//    @ConditionalOnMissingBean(UserDetailsService.class)
//    public UserDetailsService userDetailsService() {
//        UserDetails userDetails = User.withUsername("abc")
//                .password("abc")
//                .roles("USER")
//                .build();
//
//        return new InMemoryUserDetailsManager(userDetails);
//    }
//
//}
